<!--
 * @Descripttion: 
 * @Author: jhw
 * @Date: 2023-05-31 18:48:33
 * @LastEditors: jhw
 * @LastEditTime: 2023-06-28 18:17:37
-->
<template>
  <div class="tetrisDemo">
    <div class="tetris_container">
      <el-button @click="handleReset">重置</el-button>
    </div>
    <Checkerboard :checkerboard-info="checkerboardInfo"></Checkerboard>
    <div class="information">
      <el-button @click="moveLeft">左移</el-button>
      <el-button @click="moveRight">右移</el-button>
      <el-button @click="moveDown">下移</el-button>
      <el-button @click="rotate">旋转</el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, reactive } from 'vue';
import Checkerboard from './components/Checkerboard.vue';

interface MyObject {
  [key: string]: Array<Array<number>>;
}

// 定义一个12*20二维数组，用于存储方块的位置信息
const checkerboardInfo = reactive<Array<Array<number>>>(new Array(20).fill(0).map(() => new Array(12).fill(0)));

// 存储当前已经稳定坠落的方块的坐标
let stabilitySquareCoordinate = [];

//存储当前还在坠落的方格坐标
let moveSquareCoordinate = [...new Array(20).fill(0).map(() => new Array(12).fill(0))];

// 定义定时器用于后续消除
let timer: any = null;

// 方块
const tetrominoes: MyObject = {
  I: [
    [1, 0, 0, 0],
    [1, 0, 0, 0],
    [1, 0, 0, 0],
    [1, 0, 0, 0],
  ],
  O: [
    [1, 1],
    [1, 1],
  ],
  L: [
    [1, 0, 0],
    [1, 0, 0],
    [1, 1, 0],
  ],
  J: [
    [1, 1, 0],
    [1, 0, 0],
    [1, 0, 0],
  ],
  S: [
    [1, 0, 0],
    [1, 1, 0],
    [0, 1, 0],
  ],
  Z: [
    [0, 1, 0],
    [1, 1, 0],
    [1, 0, 0],
  ],
  T: [
    [1, 1, 1],
    [0, 1, 0],
    [0, 0, 0],
  ],
};

// 将转换后的二进制数字补全12位
const coverBinary: any = (str: string) => {
  return str.length < 12 ? coverBinary('0' + str) : str;
};

// 重置moveSquareCoordinate
const resetMoveSquareCoordinate = () => {
  moveSquareCoordinate = [...new Array(20).fill(0).map(() => new Array(12).fill(0))];
};

// 最小列数
const minColumn = (rowIndex: number) => {
  let length = player.length;
  let colList = [];
  for (let i = 0; i < length; i++) {
    let col = moveSquareCoordinate[rowIndex + i].findIndex((item) => item === 1);
    colList.push(col <= 0 ? 0 : col);
  }
  console.log(length, colList, 'colList');

  return Math.min(...colList);
};

// 随机生成一个方块
const createTetromino = () => {
  const index = Math.floor(Math.random() * Object.keys(tetrominoes).length);
  JSON.parse(JSON.stringify(Object.values(tetrominoes)[5])).forEach((row, i) => {
    row.forEach((item, j) => {
      moveSquareCoordinate[i][j] = item;
    });
  });
  // return JSON.parse(JSON.stringify(Object.values(tetrominoes)[index]));
  return JSON.parse(JSON.stringify(Object.values(tetrominoes)[5]));
};

// 棋盘清空
const clearCheckerboard = () => {
  checkerboardInfo.forEach((row) => row.fill(0));
};

// 改变棋盘颜色
const putTetromino = (tetromino: Array<Array<number>>) => {
  tetromino.forEach((row, i) => {
    row.forEach((item, j) => {
      if (item === 0) return;
      checkerboardInfo[i][j] = item;
    });
  });
  // console.log(checkerboardInfo, 'putTetromino初始化');
};

let player = createTetromino();

// 左移
const moveLeft = () => {
  console.log(moveSquareCoordinate, '左移');
  // 临界点判断
  if (moveSquareCoordinate.some((row) => (Number('0b' + row.join('')) & 2048) === 2048)) {
    return;
  }
  const arr = moveSquareCoordinate.reduce((prev, cur) => {
    let num = (Number('0b' + cur.join('')) << 1).toString(2);
    let newCur = coverBinary(num)
      .split('')
      .map((item: string) => Number(item));
    prev.push(newCur);
    return prev;
  }, []);
  // 清空棋盘
  clearCheckerboard();
  putTetromino(arr);
  moveSquareCoordinate = arr;
};

// 右移
const moveRight = () => {
  //  临界点判断
  if (moveSquareCoordinate.some((row) => (Number('0b' + row.join('')) & 1) === 1)) {
    return;
  }
  // 对moveSquareCoordinate降维处理
  const arr = moveSquareCoordinate.reduce((prev, cur) => {
    // 如果cur为空，不需要累加
    // if (Number('0b' + cur.join('')) === 0) return prev;
    let num = (Number('0b' + cur.join('')) >> 1).toString(2);
    let newCur = coverBinary(num)
      .split('')
      .map((item: string) => Number(item));
    prev.push(newCur);
    return prev;
  }, []);
  // 清空棋盘
  clearCheckerboard();
  putTetromino(arr);
  moveSquareCoordinate = arr;
  console.log(arr);
};

// 下移
const moveDown = () => {
  console.log(moveSquareCoordinate, '下移');
  // 临界点判断
  if (moveSquareCoordinate[moveSquareCoordinate.length - 1].join('') !== '000000000000') {
    return;
  }
  const arr = [[...new Array(12).fill(0)], ...moveSquareCoordinate.slice(0, -1)];
  clearCheckerboard();
  putTetromino(arr);
  moveSquareCoordinate = arr;
  console.log(arr, '下移之后');
};

// 旋转
const rotate = () => {
  console.log(moveSquareCoordinate, '旋转前');
  // 旋转后的方块
  const rotateTetromino = [...player.map((item: Array<number>) => [...new Array(item.length).fill(0)])];
  for (let i = 0; i < player.length; i++) {
    for (let j = 0; j < player[i].length; j++) {
      rotateTetromino[i][j] = player[player.length - 1 - j][i];
    }
  }
  player = rotateTetromino;
  console.log(rotateTetromino, '旋转后');

  // 从moveSquareCoordinate找出之前的方块
  const rowIndex = moveSquareCoordinate.findIndex((row) => row.join('') !== '000000000000');
  // const colIndex = moveSquareCoordinate[rowIndex].findIndex((item) => item === 1);
  const colIndex = minColumn(rowIndex);
  console.log(rowIndex, colIndex, 'rowIndex');
  resetMoveSquareCoordinate();
  moveSquareCoordinate.forEach((row, i) => {
    row.forEach((col, j) => {
      if (rowIndex === i && colIndex === j) {
        // moveSquareCoordinate[i].splice(j, rotateTetromino[0].length, ...rotateTetromino[0]);
        rotateTetromino.forEach((row, k) => {
          moveSquareCoordinate[i + k].splice(j, rotateTetromino[k].length, ...rotateTetromino[k]);
        });
      }
    });
  });
  console.log(moveSquareCoordinate, 'moveSquareCoordinate');
  // clearCheckerboard();
  // putTetromino(moveSquareCoordinate);

  // const rotateTetromino = moveSquareCoordinate[0].map((item, i) => player.map((row) => row[i]).reverse());
  // moveSquareCoordinate = rotateTetromino;
  // console.log(rotateTetromino, '旋转后');
};

// 重置
const handleReset = () => {
  clearCheckerboard();
  // 重置player 不能直接传值，否则player会指向同一个地址
  player = createTetromino();
  putTetromino(player);
  console.log(checkerboardInfo, 'player重置');
};
// 初始化棋盘
const init = () => {
  putTetromino(player);
};

// 默认开启一个定时器，每隔一秒下移一次
// timer = setInterval(() => {
//   moveDown();
// }, 1000);

onMounted(() => {
  init();
});
</script>

<style lang="scss" scoped>
.tetrisDemo {
  margin: 0;
  width: 100%;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgb(54 44 44);
  background-image: url('@/assets/bg.png');
  background-position: center;
}

// .tetris_container {
//   display: flex;
//   flex-direction: column;
//   margin-right: 5rem;
// }

// button {
//   width: 90px;
//   height: 45px;
//   margin-bottom: 1rem;
//   border-radius: 1000px;
// }

// button {
//   outline: none;
// }

// #score {
//   font-size: 2rem;
// }

// .information {
//   color: #fff;
//   margin-left: 5rem;
// }
</style>
